using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Data;
using System.Windows.Forms;

namespace Subro.Controls
{
    /// <summary>
    /// Arrow on the edge of a control to get to the next part
    /// 
    [DefaultEvent("Click")]
    public class ButtonMore : System.Windows.Forms.UserControl
    {
        public ButtonMore()
        {
            base.Dock = DockStyle.Bottom;
            this.SetStyle(ControlStyles.UserPaint |
                ControlStyles.ResizeRedraw |
                ControlStyles.AllPaintingInWmPaint, true);
        }

        #region Property overrides
        [DefaultValue(DockStyle.Bottom)]
        public override DockStyle Dock
        {
            get { return base.Dock; }
            set
            {
                if (value != DockStyle.None && value != DockStyle.Fill)
                    base.Dock = value;
            }
        }

        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public override AnchorStyles Anchor
        {
            get { return AnchorStyles.None; }
            set { }
        }
        #endregion

        private bool autoreverse = false;
        /// <summary>
        /// If this value is set to <c>true, the control switches
        /// <see cref="ReverseArrow"/> automatically each time the control
        /// is clicked.
        /// 
        [DefaultValue(false)]
        public bool AutoReverseArrow
        {
            get { return autoreverse; }
            set { autoreverse = value; }
        }


        private bool reverse;
        /// <summary>
        /// Normally the arrow points in the direction this control is docked to, but
        /// with this property set to <c>true, the arrow can point the other way. Usefull
        /// for scenarios where a part is shown and hidden again
        /// 
        /// <value>
        [DefaultValue(false)]
        public bool ReverseArrow
        {
            get { return reverse; }
            set
            {
                reverse = value;
                this.Invalidate();
            }
        }

        private void setdirection(ref float b, ref float c)
        {
            switch (Dock)
            {
                case DockStyle.Right: break;
                case DockStyle.Left: b *= -1; break;
                case DockStyle.Top: c = b; b = 0; break;
                case DockStyle.Bottom: c = b * -1; b = 0; break;
            }
            if (reverse)
            {
                b *= -1; c *= -1;
            }
        }

        private Border3DStyle borderstyle = Border3DStyle.Raised;
        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            ControlPaint.DrawBorder3D(
                e.Graphics, ClientRectangle, borderstyle);

            //center
            Point p = new Point(Width / 2, Height / 2);
            if (borderstyle == Border3DStyle.Sunken)
            {
                p.Offset(1, 1);
            }

            float
                perc = .6f,
                b = Math.Min(Width, Height) * perc * .5f,
                c = 0;
            GraphicsPath gp = new GraphicsPath();

            setdirection(ref b, ref c);
            try
            {
                gp.AddPolygon(
                    new PointF[]{
                    new PointF(p.X-b-c,p.Y -b+c),
                    new PointF(p.X+b,p.Y-c),
                    new PointF(p.X-b+c,p.Y+b+c)
                });
                e.Graphics.DrawPath(new Pen(Color.Black, 2), gp);
                e.Graphics.FillPath(Brushes.Navy, gp);
            }
            catch { }
        }
        protected override void OnMouseDown(MouseEventArgs e)
        {
            borderstyle = Border3DStyle.Sunken;
            Invalidate();
            base.OnMouseDown(e);
        }
        protected override void OnMouseUp(MouseEventArgs e)
        {
            borderstyle = Border3DStyle.Raised;
            Invalidate();
            base.OnMouseUp(e);
        }

        protected override void OnClick(EventArgs e)
        {
            if (autoreverse)
                this.ReverseArrow = !reverse;
            base.OnClick(e);
        }
    }
}